<template>
  <div class="search-page mr-20">
    <div :class="{ 'input-box': true, 'is-focus': isFocus }" @mouseover="onMouseover" @mouseout="onMouseout">
      <slot>
      </slot>
      <span class="icon-box ml-5 mr-10">
        <!-- 头部icon -->
        <slot name="suffix-icon">
          <i class="el-icon-search"></i>
        </slot>
      </span>
      <input ref="inputRef" :type="type" :value="value" @input="inputFn" @focus.prevent="focus" @blur.prevent="blur">
      <!-- 清除icon -->
      <span v-if="(isFocus || (clearable && showClear)) && value" class="icon-box clear-icon-box"
        @mousedown.stop.prevent="onClear">
        <slot name="clear-icon">
          <i class="el-icon-circle-close"></i>
        </slot>
      </span>
      <span class="icon-box mr-5">
        <!-- 尾部icon -->
        <slot name="prefix-icon">
          <i class="el-icon-date"></i>
        </slot>
      </span>
      <div v-if="searchAction && searchData.length && showSearchData" class="search-list">
        <div v-for="(item) in searchData" :key="item.id" class="pointer" @click="choose(item.name)">{{ item.name }}
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import axios from 'axios';
import request from '@/utils/request'
let timer = null
export default {
  props: {
    type: {  // input框的类型限制,限制属性的类型,别的属性报错
      validator: function (value) {
        return ['text', 'number', 'password'].includes(value)
      }
    },
    value: {  // v-model绑定的值,vue中input框只能是value,如果是check类型就是checked
      type: String | Number,
      default: ''
    },
    searchAction: {
      type: String | Boolean, //如果是String就是url,子组件自己调用接口获取数据,如果是true,父组件自己调用接口
      default: false
    },
    searchList: {   // 父组件传过来的模糊查询的数据
      type: Array,
      default: () => []
    },
    clearable: {  // 是否显示清除按钮
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      myList: [],  // 子组件自己调接口的模糊查询的数据
      showClear: false, // 是否显示clear Icon
      isFocus: false, // 是否聚焦,
      showSearchData: false // 控制显示模糊查询列表
    }
  },
  computed: {
    searchData: function () {
      if (typeof this.searchAction === 'boolean') {
        return this.searchList
      } else {
        return this.myList
      }
    }
  },
  mounted() {
    if (this.searchAction) this.showSearchData = true
    this.search('')
  },
  methods: {
    // 选择某一项
    choose(val) {
      this.$emit('input', val)
      this.showSearchData = false
    },
    // 点击清除icon
    onClear(e) {
      this.$emit('input', '')
      this.$refs.inputRef.focus()
      e.stopPropagation()
      this.search('')
    },
    // 获取焦点
    focus(e) {
      if (this.clearable) this.showClear = true
      this.isFocus = true
      this.$emit('focus',)
    },
    // 失去焦点
    blur(e) {
      this.isFocus = false
      if (this.clearable) this.showClear = false
      this.$emit('blur')
    },
    // 鼠标移入
    onMouseover(e) {
      if (this.clearable) this.showClear = true
      this.$emit('onMouseover')
    },
    // 鼠标移出
    onMouseout(e) {
      if (this.clearable) this.showClear = false
      this.$emit('onMouseout')
    },
    // input 事件
    inputFn(e) {
      let _val = e.target.value
      this.$emit('input', _val)
      if (this.searchAction) {
        // 有值,证明启用了模糊查询
        if (timer) clearTimeout(timer)
        timer = setTimeout(() => {
          this.search(_val)
        }, 500)
      }
      // 无论有没有启用模糊查询,都要触发emit事件,让父组件监听到,增加扩展性
    },
    search(val) {
      this.showSearchData = true
      //模糊查询
      if (typeof this.searchAction === 'boolean') {
        // 给父组件监听
        this.$emit('search', val)
      } else if (typeof this.searchAction === 'string') {
        // 使用mock模拟的数据
        // axios({
        //   method: "get",
        //   url: this.searchAction,
        //   data: {
        //     val: val,
        //   }
        // })

        // 使用node的数据
        request({
          method: 'get',
          url: this.searchAction,
          params: {
            val: val,
          }
        })
          .then(res => {
            console.log("🚀 ~ search ~ res:", res)
            this.myList = res.data.list
            this.$emit('search', val)
          })
      }
    },
  },
}

</script>
<style scoped lang='less'>
.search-page {
  display: inline-block;
  width: 100%;

  input {
    height: 38px;
    border: none;
    line-height: 26px;
    cursor: pointer;
    font-size: 14px;
    color: #606266;
    width: calc(100% - 30px);
  }

  .input-box {
    cursor: pointer;
    position: relative;
    border: 1px solid #b4bccc;
    border-radius: 5px;
    display: flex;
    align-items: center;

    &.is-focus {
      border-color: #409EFF;
    }

    .icon-box {
      font-size: 16px;
      color: #b4bccc;

      &.clear-icon-box {
        margin-right: 5px;
        z-index: 100000000 !important;
      }
    }

    .search-list {
      position: absolute;
      top: 20px;
      background: #fff;
    }
  }
}
</style>